package com.microservice.common.utils;

import com.microservice.common.context.UserContext;
import lombok.extern.slf4j.Slf4j;

/**
 * 认证工具类
 * 简化从UserContext获取用户信息和权限验证的代码
 */
@Slf4j
public class AuthUtils {
    
    /**
     * 获取当前登录用户ID
     * @return 用户ID，未登录返回null
     */
    public static Long getCurrentUserId() {
        return UserContext.getUserId();
    }
    
    /**
     * 获取当前登录用户名
     * @return 用户名，未登录返回null
     */
    public static String getCurrentUsername() {
        return UserContext.getUsername();
    }

    /**
     * 获取当前登录用户名
     * @return 用户名，未登录返回null
     */
    public static String getCurrentNickname() {
        return UserContext.getNickname();
    }
    /**
     * 获取当前登录用户ID，如果未登录则抛出异常
     * @return 用户ID
     * @throws RuntimeException 未登录时抛出
     */
    public static Long requireUserId() {
        Long userId = UserContext.getUserId();
        if (userId == null) {
            log.warn("用户未登录，操作被拒绝");
            throw new RuntimeException("请先登录");
        }
        return userId;
    }
    
    /**
     * 获取当前登录用户名，如果未登录则抛出异常
     * @return 用户名
     * @throws RuntimeException 未登录时抛出
     */
    public static String requireUsername() {
        String username = UserContext.getUsername();
        if (username == null) {
            log.warn("用户未登录，操作被拒绝");
            throw new RuntimeException("请先登录");
        }
        return username;
    }
    
    /**
     * 验证当前用户是否有权限访问指定用户ID的资源
     * @param targetUserId 目标用户ID
     * @throws RuntimeException 无权限时抛出
     */
    public static void checkUserPermission(Long targetUserId) {
        Long currentUserId = requireUserId();
        if (!currentUserId.equals(targetUserId)) {
            log.warn("用户 {} 尝试访问用户 {} 的资源，权限不足", currentUserId, targetUserId);
            throw new RuntimeException("无权访问其他用户的资源");
        }
    }
    
    /**
     * 验证当前用户是否有权限访问指定用户名的资源
     * @param targetUsername 目标用户名
     * @throws RuntimeException 无权限时抛出
     */
    public static void checkUserPermission(String targetUsername) {
        String currentUsername = requireUsername();
        if (!currentUsername.equals(targetUsername)) {
            log.warn("用户 {} 尝试访问用户 {} 的资源，权限不足", currentUsername, targetUsername);
            throw new RuntimeException("无权访问其他用户的资源");
        }
    }
    
    /**
     * 检查用户是否已登录
     * @return true-已登录，false-未登录
     */
    public static boolean isLogin() {
        return UserContext.getUserId() != null;
    }
    
    /**
     * 获取当前用户信息（包含ID和用户名）
     * @return 用户信息，未登录返回null
     */
    public static UserContext.UserInfo getCurrentUser() {
        return UserContext.getUser();
    }
    
    /**
     * 检查当前用户是否拥有指定权限
     * @param permissionCode 权限编码（如：user:read）
     * @return true-有权限，false-无权限
     */
    public static boolean hasPermission(String permissionCode) {
        UserContext.UserInfo userInfo = UserContext.getUser();
        if (userInfo == null || userInfo.getPermissions() == null) {
            return false;
        }
        return userInfo.getPermissions().contains(permissionCode);
    }
    
    /**
     * 检查当前用户是否拥有指定角色
     * @param roleCode 角色编码（如：ROLE_ADMIN）
     * @return true-有角色，false-无角色
     */
    public static boolean hasRole(String roleCode) {
        UserContext.UserInfo userInfo = UserContext.getUser();
        if (userInfo == null || userInfo.getRoles() == null) {
            return false;
        }
        return userInfo.getRoles().contains(roleCode);
    }
    
    /**
     * 要求当前用户拥有指定权限，否则抛出异常
     * @param permissionCode 权限编码
     * @throws RuntimeException 权限不足时抛出
     */
    public static void requirePermission(String permissionCode) {
        if (!hasPermission(permissionCode)) {
            log.warn("用户 {} 缺少权限: {}", getCurrentUserId(), permissionCode);
            throw new RuntimeException("权限不足：缺少权限 " + permissionCode);
        }
    }
    
    /**
     * 要求当前用户拥有指定角色，否则抛出异常
     * @param roleCode 角色编码
     * @throws RuntimeException 权限不足时抛出
     */
    public static void requireRole(String roleCode) {
        if (!hasRole(roleCode)) {
            log.warn("用户 {} 缺少角色: {}", getCurrentUserId(), roleCode);
            throw new RuntimeException("权限不足：需要角色 " + roleCode);
        }
    }
    
    /**
     * 检查当前用户是否拥有任一权限
     * @param permissionCodes 权限编码数组
     * @return true-拥有任一权限，false-没有任何权限
     */
    public static boolean hasAnyPermission(String... permissionCodes) {
        for (String permissionCode : permissionCodes) {
            if (hasPermission(permissionCode)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 检查当前用户是否拥有所有权限
     * @param permissionCodes 权限编码数组
     * @return true-拥有所有权限，false-缺少部分权限
     */
    public static boolean hasAllPermissions(String... permissionCodes) {
        for (String permissionCode : permissionCodes) {
            if (!hasPermission(permissionCode)) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 检查当前用户是否拥有任一角色
     * @param roleCodes 角色编码数组
     * @return true-拥有任一角色，false-没有任何角色
     */
    public static boolean hasAnyRole(String... roleCodes) {
        for (String roleCode : roleCodes) {
            if (hasRole(roleCode)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 检查当前用户是否拥有所有角色
     * @param roleCodes 角色编码数组
     * @return true-拥有所有角色，false-缺少部分角色
     */
    public static boolean hasAllRoles(String... roleCodes) {
        for (String roleCode : roleCodes) {
            if (!hasRole(roleCode)) {
                return false;
            }
        }
        return true;
    }
}
